package com.amumu.drama.common.config.redis;


import cn.hutool.core.collection.CollUtil;
import com.beust.jcommander.internal.Lists;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by freethinker on 2022-02-14.
 */
@Component
@Configuration(proxyBeanMethods = false)
public class RateLimitConfig implements IConfig {

    private static final Logger LOG = LoggerFactory.getLogger(RateLimitConfig.class);

    /** 限流器配置MAP */
    public static Map<AppRateLimitType, JedisRateLimiterConfig> RATE_LIMITER_CONFIG_MAP = new HashMap<>();

    /** 限流异常降级处理 */
    public static int PASS_IF_ERROR = 1;

    @PostConstruct
    public void configLimit() {
        List<RateLimit> rateLimits = Lists.newArrayList();
        RateLimit rateLimit = new RateLimit();
        rateLimit.setName(AppRateLimitType.ORDER.getName());
        rateLimit.setLimitCount(1);
        rateLimit.setEnable(1);
        rateLimit.setSpanSeconds(1);
        rateLimits.add(rateLimit);
        setRateLimiterConfigMap(rateLimits);
    }

    public void setRateLimiterConfigMap(List<RateLimit> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        RATE_LIMITER_CONFIG_MAP.clear();
        for (RateLimit o : list) {
            if (o.getEnable() == 0) {
                continue;
            }
            String name = o.getName();
            AppRateLimitType limitType = AppRateLimitType.parse(name);
            if (limitType == null) {
                LOG.error("无法匹配 AppRateLimitType（apolloKey=app.rateLimit, name={})", name);
                continue;
            }
            JedisRateLimiterConfig cfg = new JedisRateLimiterConfig("appLimit_" + o.getName(), o.getLimitCount(), o.getSpanSeconds());
            RATE_LIMITER_CONFIG_MAP.put(limitType, cfg);
        }
    }

    @Value("${app.rateLimit.passIfError:1}")
    public void setPassIfError(int val) {
        PASS_IF_ERROR = val;
    }

    @NoArgsConstructor
    @Getter
    @Setter
    private static class RateLimit implements Serializable {

        private static final long serialVersionUID = 1L;

        private String name;

        /** 是否启用（0-不启用 1-启用） */
        private int enable;

        /** 时间段内限制个数 */
        private int limitCount;

        /** 时间段（秒） */
        private int spanSeconds;
    }
}
